// StateConditions.java
package org.zjx.core.util;

import org.zjx.core.state.StateAccessor;
import org.zjx.core.state.StateComponent;

import java.util.Arrays;
import java.util.function.Predicate;

/**
 * 状态条件工具类 - 提供状态相关的条件判断工具方法
 *
 * 这个工具类封装了常见的状态条件检查逻辑，如组件存在性检查等，
 * 并提供了构建复杂条件组合的流畅API。
 */
public final class StateConditions {
    // 私有构造器防止实例化，因为这是一个纯工具类
    private StateConditions() {}

    /**
     * 检查是否包含所有指定组件
     *
     * @param accessor 要检查的状态
     * @param componentTypes 要检查的组件类型数组
     * @return 如果状态快照包含所有指定类型的组件则返回true，否则false
     */
    @SafeVarargs
    public static boolean hasAllComponents(
            StateAccessor accessor,
            Class<? extends StateComponent>... componentTypes) {
        return Arrays.stream(componentTypes)
                .allMatch(accessor::containsComponent);
    }

    /**
     * 创建组件谓词
     *
     * @param requiredComponents 需要的组件类型数组
     * @return 一个Predicate，当状态快照包含所有指定组件时返回true
     */
    @SafeVarargs
    public static Predicate<StateAccessor> createComponentPredicate(
            Class<? extends StateComponent>... requiredComponents
    ) {
        return accessor  -> hasAllComponents(accessor , requiredComponents);
    }

    /**
     * 复合条件构建器入口
     *
     * 开始构建一个复合条件，首先检查指定的组件类型是否存在。
     *
     * @param firstType 第一个需要检查的组件类型
     * @return 复合条件构建器实例
     */
    public static AccessorConditionBuilder  when(Class<? extends StateComponent> firstType) {
        return new AccessorConditionBuilder().and(firstType);
    }

    /**
     * 复合条件构建器 - 提供流畅API构建复杂的状态条件
     */
    public static final class AccessorConditionBuilder  {
        private Predicate<StateAccessor> predicate = accessor -> true;

        /**
         * 添加AND条件
         */
        public AccessorConditionBuilder and(Class<? extends StateComponent> type) {
            predicate = predicate.and(accessor -> accessor.containsComponent(type));
            return this;
        }

        /**
         * 添加自定义条件
         */
        public AccessorConditionBuilder and(Predicate<StateAccessor> condition) {
            predicate = predicate.and(condition);
            return this;
        }

        /**
         * 构建最终谓词
         */
        public Predicate<StateAccessor> build() {
            return predicate;
        }
    }

    /**
     * 检查组件是否满足条件（实时版本）
     */
    public static <T extends StateComponent> Predicate<StateAccessor> componentMatches(
            Class<T> componentType,
            Predicate<T> condition) {
        return accessor -> accessor.getComponent(componentType)
                .map(condition::test)
                .orElse(false);
    }
}